from generated import student_pb2, student_pb2_grpc
from api.http.model.student_model import Gender as StudentGender, StudentUpdate, StudentCreate
from api.http.service.student_service import StudentService
from api.grpc.decorator.exception_decorator import grpc_exception_handler, validate_request
from api.grpc.interceptor.exception_interceptor import ValidationException, NotFoundException


class StudentGRPCService(student_pb2_grpc.StudentServiceServicer):
    def __init__(self):
        self.student_service = StudentService()

    @staticmethod
    def _validate_student_data_static(request):
        """静态参数验证方法，用于装饰器"""
        if not request.name or len(request.name) < 2 or len(request.name) > 50:
            raise ValidationException("姓名长度必须在 2 到 50 个字符之间")
        if request.age < 0 or request.age > 150:
            raise ValidationException("年龄必须在 0 到 150 岁之间")
        return True

    def _validate_student_data(self, request):
        """参数验证方法"""
        return self._validate_student_data_static(request)

    @grpc_exception_handler
    @validate_request(lambda req: StudentGRPCService._validate_student_data_static(req))
    def CreateStudent(self, request, context):
        gender = StudentGender(request.gender)
        student_data = StudentCreate(**{
            "name": request.name,
            "age": request.age,
            "birth_date": request.birth_date.ToDatetime(),
            "gender": gender
        })
        student = self.student_service.create(student_data)
        return student_pb2.CreateStudentResponse(
            student=student_pb2.Student(
                id=student.id,
                name=student.name,
                age=student.age,
                birth_date=student.birth_date,
                gender=student.gender.value
            )
        )

    @grpc_exception_handler
    def GetStudent(self, request, context):
        student = self.student_service.read(request.id)
        if not student:
            raise NotFoundException("学生未找到")
        return student_pb2.GetStudentResponse(
            student=student_pb2.Student(
                id=student.id,
                name=student.name,
                age=student.age,
                birth_date=student.birth_date,
                gender=student.gender.value
            )
        )

    @grpc_exception_handler
    def GetAllStudents(self, request, context):
        students = self.student_service.read_all()
        response = student_pb2.GetAllStudentsResponse()
        for student in students:
            response.students.append(
                student_pb2.Student(
                    id=student.id,
                    name=student.name,
                    age=student.age,
                    birth_date=student.birth_date,
                    gender=student.gender.value
                )
            )
        return response

    @grpc_exception_handler
    @validate_request(lambda req: StudentGRPCService._validate_student_data_static(req))
    def UpdateStudent(self, request, context):
        gender = StudentGender(request.gender)
        student_data = StudentUpdate(**{
            "name": request.name,
            "age": request.age,
            "birth_date": request.birth_date.ToDatetime(),
            "gender": gender
        })
        updated_student = self.student_service.update(request.id, student_data)
        if not updated_student:
            raise NotFoundException("学生未找到")
        return student_pb2.UpdateStudentResponse(
            student=student_pb2.Student(
                id=updated_student.id,
                name=updated_student.name,
                age=updated_student.age,
                birth_date=updated_student.birth_date,
                gender=updated_student.gender.value
            )
        )

    @grpc_exception_handler
    def DeleteStudent(self, request, context):
        success = self.student_service.delete(request.id)
        if not success:
            raise NotFoundException("学生未找到")
        return student_pb2.DeleteStudentResponse(success=True)
